<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2024/3/20
 * Time: 11:46
 */

namespace app\queue\tool;

use app\common\lib\Common;
use app\common\lib\Puppeteer;
use app\common\lib\RedisQueue;
use app\common\lib\TencentAsr;
use app\exception\IndexException;
use app\logic\index\tool\ToolManageLogic;
use app\model\redis\RedisQueueModel;
use app\model\tool\ToolArticleChangeCommandModel;
use app\model\tool\ToolManageModel;
use app\model\tool\UserToolArticleModel;
use app\model\tool\UserToolVideoModel;
use support\Cache;
use support\Context;
use support\Db;
use support\Request;
use Webman\RedisQueue\Consumer;
use app\common\lib\TencentCos;

class AiGeneratedContent  implements Consumer
{
    // 要消费的队列名
    public $queue = 'aiGenerateContent';

    // 连接名，对应 plugin/webman/redis-queue/redis.php 里的连接`
    public $connection = 'default';

    protected $resultData = [];

    // 消费
    public function consume($data)
    {
        Common::initQueueConfig();

        $queue = RedisQueueModel::getInstance()->find($data['queueid']);
        $queue->exec_time = date('Y-m-d H:i:s');
        $queue->save();

        try{

            $result = $this->handle($data);

            RedisQueue::getInstance()->saveQueue($this->queue,$data,$result);
        }catch (\Throwable $e){
            RedisQueue::getInstance()->saveQueue($this->queue,$data,['error'=>$e->getMessage()]);
            Common::queueExecptionReport($queue,$data,$e);
        }
    }

    protected function handle($data)
    {
        Context::set(\Webman\Http\Request::class, (new Request([])));
        switch ($data['tool_type']){
            case 'video_water':
                return  $this->videoWater($data);
            case 'video_word':
                return $this->videoWord($data);
            case 'article_change':
            case 'article_part':
            case 'article_head_change':
            case 'article_keyword':
                return $this->articleContentChange($data);
        }

    }

    protected function videoWater($data)
    {
        $first = UserToolVideoModel::getInstance()->find($data['id']);
        $tool = ToolManageModel::getInstance()->find($data['tool_id']);
        if($first==false || $tool==false || empty($first['content'])){
            throw new IndexException(4020,'数据不存在');
        }
        try{
            $videoLink = Puppeteer::getInstance()->getVideoLink($first['content']);
            $name = substr(md5(round(microtime(true)*10000).Common::rand_string(8)),-20);
            $filePath = runtime_path('tool/'.date('ymd').'/'.$name.'.mp4');
            Common::mkdirs(dirname($filePath));
            $res = file_put_contents($filePath,file_get_contents($videoLink));
            if($res==false){
                throw new IndexException(4020,'视频提取失败');
            }
            if(is_file($videoLink)){
                @unlink($videoLink);
            }
            $res = TencentCos::getInstance()->uploadLocalFile($filePath,'tool/video');
            $videoLink = 'https://'.$res['Location'];
            @unlink($filePath);

            $first->video_link = $videoLink;
            $first->status = 1;
            $first->message = '提取成功';
            $first->save();

            if($tool['charge_type']=='3'){
                $ponintParam = [
                    'source_table'=>UserToolVideoModel::getInstance()->getTable(),
                    'sourceid'=>$first['id'],
                ];

                request()->curUserId = $first['user_sn'];
                ToolManageLogic::getInstance()->insertConsumePoint($tool['point_nums'],$ponintParam,4);
            }
            return [$videoLink];
        }catch (\Throwable $e){
            $first->status = 2;
            $first->message = $e->getCode()==4020?$e->getMessage():'提取失败';
            $first->save();
            throw $e;
        }

    }

    protected function videoWord($data)
    {
        $first = UserToolVideoModel::getInstance()->find($data['id']);
        $tool = ToolManageModel::getInstance()->find($data['tool_id']);
        if($first==false || $tool==false || (empty($first['content']) && empty($first['video_url']))){
            throw new IndexException(4020,'数据不存在');
        }
        try{
            if(!empty($first['content'])){
                $videoLink = Puppeteer::getInstance()->getVideoLink($first['content']);
                $name = substr(md5(round(microtime(true)*10000).Common::rand_string(8)),-20);
                $filePath = runtime_path('tool/'.date('ymd').'/'.$name.'.mp4');
                Common::mkdirs(dirname($filePath));
                $res = file_put_contents($filePath,file_get_contents($videoLink));
                if($res==false){
                    throw new IndexException(4020,'视频提取失败');
                }
                if(is_file($videoLink)){
                    @unlink($videoLink);
                }
                $res = TencentCos::getInstance()->uploadLocalFile($filePath,'tool/video');
                $videoLink = 'https://'.$res['Location'];
                @unlink($filePath);
            }else{
                $videoLink = $first['video_url'];
            }

            $res = TencentAsr::getInstance()->createRecTask($videoLink);

            $content = '';
            $startTime = time();
            while (true){
                $result = TencentAsr::getInstance()->describeTaskStatus($res['Data']['TaskId']);
                if(!empty($result['Data']['Status']) && $result['Data']['Status']==2){
                    if(!empty($result['Data']['Result'])){
                        $content = trim(mb_substr($result['Data']['Result'],18));
                        $content = preg_replace(['/\[[\d|,|:|.]+\]/'],'',$content);
                    }
                    $replaceStr =  ['`','~','!','@','#','$','^','&','*','(',')','=','|','{','}','\\',':',';',',','[',']','.','+','-','_',
                                    '<','>','《','》','/','?','！','￥','……','（','）','――','|','【','】',
                                    '‘','；','：','”','“','。','，','、','？',', ','\'','"','’',' '];
                    $content = str_replace($replaceStr, "\n",$content);
                    $first->video_link = $videoLink;
                    $first->video_word = $content;
                    $first->status = 1;
                    $first->message = '提取成功';
                    $first->save();

                    if($tool['charge_type']=='3'){
                        $ponintParam = [
                            'source_table'=>UserToolVideoModel::getInstance()->getTable(),
                            'sourceid'=>$first['id'],
                        ];
                        request()->curUserId = $first['user_sn'];
                        ToolManageLogic::getInstance()->insertConsumePoint($tool['point_nums'],$ponintParam,4);
                    }

                    return ['content'=>$content];
                }elseif(!empty($result['Data']['Status']) && $result['Data']['Status']==3){
                    throw new IndexException(4020,'视频提取文字失败');
                }

                if((time()-$startTime)>60){
                    throw new IndexException(4020,'视频提取文字超时');
                }
                usleep(200000);
            }
        }catch (\Throwable $e){
            $first->status = 2;
            $first->message = $e->getCode()==4020?$e->getMessage():'提取失败';
            $first->save();
            throw $e;
        }

    }

    protected function articleContentChange($data)
    {
        $first = UserToolArticleModel::getInstance()->find($data['id']);
        $tool = ToolManageModel::getInstance()->find($data['tool_id']);
        if($first==false || $tool==false || empty($first['content'])){
            throw new IndexException(4020,'数据不存在');
        }

        try{
            $command = '';
            if($first['type']==1){
                $command = ToolArticleChangeCommandModel::getInstance()->find($first['model_id']);
                if($command==false){
                    throw new IndexException(4020,'风格不存在');
                }
                if(strpos($command['command_content'],'@content')===false){
                    $command['command_content'] .= "\n @content";
                }
                $command = $command['command_content'];
            }elseif($first['type']==2){
                $command = getAiCommand('content_parts_ai_command');
                if(strpos($command,'@content')===false){
                    $command .= "\n @content";
                }
            }elseif($first['type']==3){
                $command = getAiCommand('article_head_analyze_command');
                if(strpos($command,'@content')===false){
                    $command .= "\n @content";
                }
            }elseif($first['type']==4){
                $command = getAiCommand('keyword_generater_command');
                if(strpos($command,'@content')===false){
                    $command .= "\n @content";
                }
            }

            if(empty($command)){
                throw new IndexException(4020,'命令不存在');
            }
            $content = Common::generatedContent($first['content'], $command);
            $content = str_replace(['、','，'],',',$content);

            $first->analyze_content = $content;
            $first->command_content = $command;
            $first->status = 1;
            $first->message = '成功';
            $first->save();

            if($tool['charge_type']=='3'){
                $ponintParam = [
                    'source_table'=>UserToolArticleModel::getInstance()->getTable(),
                    'sourceid'=>$first['id'],
                ];
                request()->curUserId = $first['user_sn'];
                ToolManageLogic::getInstance()->insertConsumePoint($tool['point_nums'],$ponintParam,4);
            }

            return ['content'=>$content];
        }catch (\Throwable $e){
            if($e->getCode()==4049 || strpos($e->getMessage(),'敏感词')!==false){
                $first->status = 3;
                $first->message = $e->getMessage();
                $first->save();
            }else{
                $first->status = 2;
                $first->message = $e->getMessage();
                $first->save();
            }
        }
    }

    // 消费失败回调
    /*
    $package = [
        'id' => 1357277951, // 消息ID
        'time' => 1709170510, // 消息时间
        'delay' => 0, // 延迟时间
        'attempts' => 2, // 消费次数
        'queue' => 'send-mail', // 队列名
        'data' => ['to' => 'tom@gmail.com', 'content' => 'hello'], // 消息内容
        'max_attempts' => 5, // 最大重试次数
        'error' => '错误信息' // 错误信息
    ]
    */
    public function onConsumeFailure(\Throwable $e, $package)
    {
//        echo "consume failure\n";
//        echo $e->getMessage() . "\n";
//        // 无需反序列化
//        var_export($package);

        RedisQueue::getInstance()->saveQueue($this->queue,$package['data'],['error'=>$e->getMessage()]);
    }

}